package com.own.business.wallet.business.service.impl;

import com.own.business.wallet.business.service.WalletService;
import com.own.business.wallet.common.em.WalletExceptionEnum;
import com.own.business.wallet.common.property.WalletPayPasswordProperty;
import com.own.business.wallet.entity.bo.WalletBo;
import com.own.business.wallet.entity.map.WalletMapVo;
import com.own.business.wallet.entity.po.Wallet;
import com.own.business.wallet.entity.query.WalletQuery;
import com.own.business.wallet.entity.vo.WalletVo;
import com.own.business.wallet.mapper.WalletMapper;
import com.own.component.common.base.service.impl.AbstractBaseService;
import com.own.component.common.exception.BusinessSimpleException;
import com.own.component.common.util.encrypt.EncryptUtil;
import com.own.component.store.core.util.LockStoreUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * WalletServiceImpl
 *
 * @author chenxueli
 * @date 2023-07-13 16:07:39
 */
@Slf4j
@Service
public class WalletServiceImpl extends AbstractBaseService<
        Wallet,
        WalletBo,
        WalletVo,
        WalletMapVo,
        WalletQuery,
        WalletMapper
        > implements WalletService {

    @Resource
    private WalletMapper walletMapper;

    @Resource
    private WalletPayPasswordProperty walletPayPasswordProperty;

    @Resource
    private LockStoreUtil lockStoreUtil;

    /**
     * 根据用户id获取钱包数据
     *
     * @param userId 用户id
     * @return 钱包数据
     */
    @Override
    public Wallet getByUserId(Long userId) {
        var wrapper = lambdaQueryWrapper().eq(Wallet::getFkUserId, userId);
        var wallet = walletMapper.selectOne(wrapper);
        if (wallet != null) {
            return wallet;
        }
        // 创建新的钱包
        return lockStoreUtil.lock("o:c:wallet:" + userId, () -> {
            var po = new Wallet();
            po.setFkUserId(userId);
            po.setBalance(0);
            po.setFreezeAmount(0);
            po.setPassword(null);
            po.setIsWithoutPassword(0);
            walletMapper.insert(po);
            return po;
        });
    }

    /**
     * 验证支付密码是否正确
     *
     * @param userId   用户id
     * @param password 支付密码
     * @return 是否正确
     */
    @Override
    public boolean checkPassword(Long userId, String password) {
        var wallet = getByUserId(userId);
        if (wallet.getIsWithoutPassword() == 1) {
            return true;
        }
        if (StringUtils.isBlank(wallet.getPassword())) {
            throw new BusinessSimpleException(WalletExceptionEnum.NEED_SET_PAY_PASSWORD);
        }
        return StringUtils.equals(wallet.getPassword(), EncryptUtil.MD5.encrypt(password));
    }

    /**
     * 修改密码
     *
     * @param userId   用户id
     * @param password 密码
     */
    @Override
    public void updatePassword(Long userId, String password) {
        var wallet = getByUserId(userId);
        if (StringUtils.isBlank(password)) {
            throw new BusinessSimpleException("密码不能为空");
        }
        // 必须是纯数字
        var regex = "^[0-9]{" + walletPayPasswordProperty.getLength() + "}$";
        if (!password.matches(regex)) {
            throw new BusinessSimpleException("密码为" + walletPayPasswordProperty.getLength() + "位纯数字");
        }
        walletMapper.updatePassword(wallet.getId(), EncryptUtil.MD5.encrypt(password));
    }

    /**
     * 增加余额
     *
     * @param id      钱包id
     * @param balance 余额
     */
    @Override
    public void increase(Long id, Integer balance) {
        walletMapper.increase(id, balance);
    }

    /**
     * 减少余额
     *
     * @param id      钱包id
     * @param balance 余额
     */
    @Override
    public void decrease(Long id, Integer balance) {
        walletMapper.decrease(id, balance);
    }

}
